package com.woniu.user.service.impl;

import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.common.ResponseData;
import com.woniu.common.ResponseEnum;
import com.woniu.user.entity.Face;
import com.woniu.user.entity.User;
import com.woniu.user.entity.result.FaceResult;
import com.woniu.user.service.FaceContrastService;
import com.woniu.user.service.FaceService;
import com.woniu.user.mapper.FaceMapper;
import com.woniu.user.service.UserService;
import com.woniu.user.utils.JwtUtils;
import com.woniu.user.utils.TimeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
* @author hasee
* @description 针对表【face】的数据库操作Service实现
* @createDate 2025-01-05 13:53:36
*/
@Service
public class FaceServiceImpl extends ServiceImpl<FaceMapper, Face>
    implements FaceService{
    public static final String WONIU = "woniu";
    @Autowired
    private FaceContrastService faceContrastServer;
    @Autowired
    private UserService userService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public ResponseData<?> vef(String imageBase) {
        imageBase = JSONUtil.parseObj(imageBase).getStr("imageBase");
        List<Face> faceList = lambdaQuery().orderByDesc(Face::getVefNum).list();
        FaceResult faceState = null;

        // 如果人脸库为空,则第一次登录为录入人脸
//        if (faceList.size() == 0){
//            return initFace(imageBase);
//        }else {
            float score = faceContrastServer.faceLive(imageBase);
//            if (score < FaceResult.STATIC_LIVE_SCORE){
//                //return FaceResult.error(FaceResult.LIVE_ERROR,"活体检测失败");
//                return new ResponseData<>().fail(ResponseEnum.LIVE_ERROR);
//            }
            int faceLength = faceList.size();
            for (Face face : faceList) {
                FaceResult faceResult = faceContrastServer.faceContrast(face.getFaceBase(), imageBase);
                // 是否比对成功
                if (faceResult.getCode() == FaceResult.SUCCESS_CODE ){
                    // 相似度是否大于80
                    if (faceResult.getScore() > FaceResult.SATISFY_SCORE){
                        if (face.getFaceStatus() == 0){
                            // 成功,根据人脸id查询用户
                            Long accountId = face.getAccountId();
                            User user = userService.lambdaQuery().eq(User::getId, accountId).one();
                            lambdaUpdate().set(Face::getVefNum,face.getVefNum()+1).eq(Face::getFid,face.getFid()).update();
                            //faceResult.setMsg(TimeUtils.timeQuantum()+"好,"+face.getFaceName());//系统显示下午好，admin
                            //faceResult.setName(face.getFaceName());
//                            map.put("score",String.valueOf(faceResult.getScore()));
//                            map.put("faceName",faceResult.getName());
//                            faceResult.setToken(JwtUtils.genereteToken(map));
                            user.setPassword(null);
                            user.setFaceBase(null);
                            //生成token
                            HashMap map = new HashMap<>();
                            map.put("user", user);
                            String token = JWTUtil.createToken(map, WONIU.getBytes());
                            //先查看redis有无该jwt，有的话给jwt续期
                            String token2 = redisTemplate.opsForValue().get("UserToken---" + user.getId());
                            if (token2!=null) {
                                redisTemplate.expire("UserToken---" + user.getId(), 72, TimeUnit.HOURS);
                            } else {
                                redisTemplate.opsForValue().set("UserToken---" + user.getId(), token, 72, TimeUnit.HOURS);
                            }
                            return new ResponseData<>().ok(user);

                        }else {
                            // 失败 人脸被禁用
                            lambdaUpdate().set(Face::getVefNum,face.getVefNum()+1).eq(Face::getFid,face.getFid()).update();
                            faceResult.setMsg(face.getFaceName()+",当前人脸被禁用");
                            faceResult.setName(face.getFaceName());
                            faceResult.setCode(FaceResult.FORBIDDEN_FACE);
                            faceState = faceResult;
                            // 就算上一张人脸被禁用还得往下执行
                            // 可能当前用户存在多张人脸，
                            if (faceLength == 1){
                                return new ResponseData<>().ok(faceResult);
                            }
                            faceLength --;
                        }
                    }else {
                        // 人脸库没有检测到人脸
                        if (faceLength == 1){
                            // 判断当前人脸是否被禁用，如被禁用，提示被禁用
                            // 禁用优先级大于 没有检测到人脸
                            //return faceState != null?faceState:FaceResult.error(FaceResult.NOT_FOUND_FACE,"人脸库不存在该人脸",faceResult.getScore());
                        return new ResponseData<>().fail(ResponseEnum.NO_FACE);
                        }
                        faceLength --;
                    }
                }else {
                    // 接口返回异常
                    return new ResponseData<>().ok(faceResult);
                }
            }
//        }
        // 空异常
        //return FaceResult.error(FaceResult.NULL_ERROR,"空指针异常");
        return new ResponseData<>().fail(ResponseEnum.NULL_ERROR);
    }

    public FaceResult initFace(String imageBase){
        FaceResult faceResult = new FaceResult();
        Face face = new Face();
        face.setFaceBase(imageBase);
        face.setCreateTime(new Date());
        face.setVefNum(0);
        face.setFaceName("admin");
        face.setFaceStatus(0);
        boolean save = save(face);
        faceResult.setCode(FaceResult.INIT_FACE);
        faceResult.setMsg("人脸初始化"+(save?"成功":"失败")+","+(save?"请验证登录":"请稍后再试"));
        faceResult.setName(face.getFaceName());
        return faceResult;
    }
}




